/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.classdiagram.parsers.texteditor.operationlabel;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.Collection;
import java.util.Vector;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ContextInformation;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.uml2.uml.Operation;

import antlr.RecognitionException;
import antlr.TokenStreamException;

import com.cea.papyrus.classdiagram.parsers.PapyrusParsersPlugin;
import com.cea.papyrus.classdiagram.parsers.antlr.OperationLabelLexer;
import com.cea.papyrus.classdiagram.parsers.antlr.OperationLabelParser;

/**
 * Completion processor for action language. <BR>
 * Main class to process the different completions given by the texteditor
 * to its user
 * 
 * @author Remi SCHNEKENBURGER
 * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor
 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor
 * @see com.cea.actionlanguage.sharedresources.texteditor.IOperationLabelKeywords
 */
public class OperationLabelCompletionProcessor extends TemplateCompletionProcessor
implements IContentAssistProcessor, IContext {
    
    /**
     * 
     */
    public final static String RTACTION_DOT = "__rtaction_dot";
    
    /**
     * 
     */
    public final static String RTACTION_STRING = "__rtaction_string";
    
    /**
     * 
     */
    public final static String RTACTION_DEFAULT = "__rtaction_default";
    
    /**
     * 
     */
    private static final String TEMPLATE_IMAGE = "resources/icons/template.gif";
    
    /**
     * 
     */
    private Operation operation;
    
    /**
     * 
     * 
     * @param operation 
     */
    public OperationLabelCompletionProcessor(Operation operation) {
		this.operation = operation;
	}
    
    /**
     * Simple content assist tip closer. The tip is valid in a range of 1
     * characters around its popup location.
     */
    protected static class Validator implements IContextInformationValidator,
    IContextInformationPresenter {
        
        /**
         * 
         */
        protected int fInstallOffset;
        
        /*
         * @see IContextInformationValidator#isContextInformationValid(int)
         */
        /**
         * 
         * 
         * @param offset 
         * 
         * @return 
         */
        public boolean isContextInformationValid(int offset) {
            return Math.abs(fInstallOffset - offset) < 1;
        }
        
        /*
         * @see IContextInformationValidator#install(IContextInformation,
         *      ITextViewer, int)
         */
        /**
         * 
         * 
         * @param viewer 
         * @param info 
         * @param offset 
         */
        public void install(IContextInformation info, ITextViewer viewer,
                int offset) {
            fInstallOffset = offset;
        }
        
        /*
         * @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int,
         *      TextPresentation)
         */
        /**
         * 
         * 
         * @param presentation 
         * @param documentPosition 
         * 
         * @return 
         */
        public boolean updatePresentation(int documentPosition,
                TextPresentation presentation) {
            return false;
        }
    }
    
    /**
     * 
     */
    protected IContextInformationValidator fValidator = new Validator();
    
    /* (non-Javadoc)
     * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
     */
    /**
     * 
     * 
     * @param viewer 
     * @param documentOffset 
     * 
     * @return 
     */
    @Override
	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
            int documentOffset) {
    	String text;
		try {
			text = viewer.getDocument().get(0, documentOffset);
			OperationLabelLexer lexer = new OperationLabelLexer(new BufferedReader(new StringReader(text)));
			OperationLabelParser parser = new OperationLabelParser(lexer, operation);
			parser.setValidation(true);
			parser.label();
		} catch (BadLocationException e) {
			e.printStackTrace();
		} catch (RecognitionException e) {
			//e.printStackTrace();
		} catch (TokenStreamException e) {
			//e.printStackTrace();
		}
    	return new ICompletionProposal[0];
    }
    
    /* (non-Javadoc)
     * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
     */
    /**
     * 
     * 
     * @param viewer 
     * @param documentOffset 
     * 
     * @return 
     */
    @Override
	public IContextInformation[] computeContextInformation(ITextViewer viewer,
            int documentOffset) {
        IContextInformation[] result = new IContextInformation[5];
        for (int i = 0; i < result.length; i++) {
			result[i] = new ContextInformation(
                    /*
                     * MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"),
                     * new Object[] { new Integer(i), new Integer(documentOffset) }),
                     * //$NON-NLS-1$
                     * MessageFormat.format(JavaEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"),
                     * new Object[] { new Integer(i), new Integer(documentOffset - 5),
                     * new Integer(documentOffset + 5)})); //$NON-NLS-1$
                     */
                    "computeContextInfo_1", "computeContextInfo_2");
		}
        return result;
    }
    
    /*
     * (non-Javadoc) Method declared on IContentAssistProcessor
     */
    /**
     * 
     * 
     * @return 
     */
    @Override
	public char[] getCompletionProposalAutoActivationCharacters() {
        return new char[] { '.' };
    }
    
    /*
     * (non-Javadoc) Method declared on IContentAssistProcessor
     */
    /**
     * 
     * 
     * @return 
     */
    @Override
	public char[] getContextInformationAutoActivationCharacters() {
        return new char[] { '#' };
    }
    
    /*
     * (non-Javadoc) Method declared on IContentAssistProcessor
     */
    /**
     * 
     * 
     * @return 
     */
    @Override
	public IContextInformationValidator getContextInformationValidator() {
        return fValidator;
    }
    
    /*
     * (non-Javadoc) Method declared on IContentAssistProcessor
     */
    /**
     * 
     * 
     * @return 
     */
    @Override
	public String getErrorMessage() {
        return null;
    }
    
    /**
     * when computing completion proposals, this method retrieves the string on
     * which the user is computing proposals it checks recursively if the
     * character at the precedent offset is also a part of the string (is a Java
     * identifier).
     * 
     * @param viewer - the text viewer where the current document is shown
     * @param documentOffset - the offset on which the end of the calculated string is
     * 
     * @return the string that will be completed
     */
    public String getBaseString(ITextViewer viewer, int documentOffset) {
        try {
            if (documentOffset != 0) {
                char c = viewer.getDocument().getChar(documentOffset - 1);
                if (Character.isJavaIdentifierPart(c) || (c=='\'')) {
                    return getBaseString(viewer, documentOffset - 1) + c;
                }
            }
        } catch (BadLocationException e) {
            return "";
        }
        return "";
    }
    
    /* (non-Javadoc)
     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getTemplates(java.lang.String)
     */
    /**
     * 
     * 
     * @param contextTypeId 
     * 
     * @return 
     */
    @Override
	protected Template[] getTemplates(String contextTypeId) {
        return OperationLabelTemplateUI.getDefault().getTemplateStore().getTemplates();
    }
    
    /* (non-Javadoc)
     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getContextType(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
     */
    /**
     * 
     * 
     * @param viewer 
     * @param region 
     * 
     * @return 
     */
    @Override
	protected TemplateContextType getContextType(ITextViewer viewer,
            IRegion region) {
        return OperationLabelTemplateUI.getDefault().getContextTypeRegistry()
        .getContextType(OperationLabelContextType.OPERATION_LABEL_CONTEXT_TYPE);
    }
    
    /* (non-Javadoc)
     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getImage(org.eclipse.jface.text.templates.Template)
     */
    /**
     * 
     * 
     * @param template 
     * 
     * @return 
     */
    @Override
	protected Image getImage(Template template) {
        ImageRegistry registry = PapyrusParsersPlugin.getDefault().getImageRegistry();
        Image image = registry.get(TEMPLATE_IMAGE);
        if (image == null) {
            ImageDescriptor desc = AbstractUIPlugin.imageDescriptorFromPlugin(
            		PapyrusParsersPlugin.PLUGIN_ID, TEMPLATE_IMAGE);
            registry.put(TEMPLATE_IMAGE, desc);
            image = registry.get(TEMPLATE_IMAGE);
        }
        if(image == null) {
            image = PapyrusParsersPlugin.getImage(PapyrusParsersPlugin.DEFAULT_IMAGE);
        }
        return image;
    }
    
    /**
     * 
     * 
     * @param context 
     * @param prefix 
     * @param documentOffset 
     * 
     * @return 
     */
    public Collection computeCompletions(int context, String prefix, int documentOffset) {
        Collection v = new Vector();
        return v;
    }
    
    /**
     * 
     * 
     * @param proposals 
     * @param prefix 
     * @param proposalsInfo 
     * @param documentOffset 
     * 
     * @return 
     */
    public Collection createCompletionProposals(String[] proposals, String[] proposalsInfo, String prefix, int documentOffset) {
        Vector v = new Vector();
        for (int i = 0; i < proposals.length; i++) {
            // test if the proposal starts with the prefix given in parameter
            if(proposals[i].startsWith(prefix)) {
                IContextInformation info = new ContextInformation(
                        proposals[i], 
                        "context info for " + proposals[i]);
                
                v.add(new CompletionProposal(
                        proposals[i], 
                        documentOffset-prefix.length(), 
                        prefix.length(),
                        proposals[i].length(), 
                        null, 
                        proposals[i], 
                        info,
                        proposalsInfo[i]));
            }
        }
        return v;
    }
    
    /**
     * 
     * 
     * @param proposals 
     * @param proposalsName 
     * @param prefix 
     * @param proposalsInfo 
     * @param documentOffset 
     * 
     * @return 
     */
    public Collection createCompletionProposalsWithDifferentName(String[] proposals, String[] proposalsInfo, String[] proposalsName, String prefix, int documentOffset) {
        Vector v = new Vector();
        for (int i = 0; i < proposals.length; i++) {
            // test if the proposal starts with the prefix given in parameter
            if(proposals[i].startsWith(prefix)) {
                IContextInformation info = new ContextInformation(
                        proposals[i], 
                        "context info for " + proposals[i]);
                
                v.add(new CompletionProposal(
                        proposals[i], 
                        documentOffset-prefix.length(), 
                        prefix.length(),
                        proposals[i].length(), 
                        null, 
                        proposalsName[i], 
                        info,
                        proposalsInfo[i]));
            }
        }
        return v;
    }
    
    
    
}